package jmine.tec.hydra.services.alterar;

import jmine.tec.di.annotation.Injected;
import jmine.tec.hydra.api.HydraSpecification;
import jmine.tec.hydra.dao.HydraSpecificationDAO;
import jmine.tec.hydra.domain.HydraSystem;
import jmine.tec.hydra.domain.senderRegistry.AbstractSenderRegistry;
import jmine.tec.hydra.domain.specification.HydraSpecificationImpl;
import jmine.tec.script.persistent.domain.Script;
import jmine.tec.services.annotations.Execution;
import jmine.tec.services.annotations.Input;
import jmine.tec.services.annotations.Output;
import jmine.tec.services.annotations.ServiceImplementor;
import jmine.tec.services.api.ActionsEnum;
import bancosys.tec.persist.dao.BeanNotFoundException;

/**
 * Serviço de alteração de uma especificação de integração.
 * 
 * @author piercio
 */
@ServiceImplementor(action = ActionsEnum.ALTERAR)
public class HydraSpecificationService {

    public static final String IDENTIFICADOR = "Identificador";

    public static final String ACTION = "Ação";

    public static final String SYSTEM = "Sistema";

    public static final String SENDER = "Sender";

    public static final String ENCODE_SCRIPT = "Encode Script";

    public static final String DECODE_SCRIPT = "Decode Script";

    public static final String TEMPLATE_SCRIPT = "Template";

    public static final String HABILITADO = "Habilitado";

    // Injected
    private HydraSpecificationDAO dao;

    // Obrigatórios
    private String action;

    private HydraSystem system;

    private AbstractSenderRegistry sender;

    private Script encode;

    private Script template;

    private Script decode;

    private boolean enabled;

    /**
     * Executa o serviço e cria um {@link HydraSpecificationImpl}
     * 
     * @return uma especificação de integração.
     * @throws BeanNotFoundException caso não encontre a especificação para o sistema e ação.
     */
    @Execution
    @Output(propertyName = IDENTIFICADOR)
    public final HydraSpecification executeService() throws BeanNotFoundException {
        HydraSpecificationImpl spec = this.dao.findByActionSystem(this.system, this.action);
        spec.setSenderRegistry(this.sender);
        spec.setEncodeScript(this.encode);
        spec.setTemplate(this.template);
        spec.setDecodeScript(this.decode);

        if (this.enabled) {
            spec.enable();
        } else {
            spec.disable();
        }

        spec.getPersister().save();
        return spec;
    }

    /**
     * @param dao the dao to set
     */
    @Injected
    public void setDao(HydraSpecificationDAO dao) {
        this.dao = dao;
    }

    /**
     * @param action a ação da especificação.
     */
    @Input(fieldName = ACTION)
    public void setAction(String action) {
        this.action = action;
    }

    /**
     * @param system o sistema da especificação.
     */
    @Input(fieldName = SYSTEM)
    public void setSystem(HydraSystem system) {
        this.system = system;
    }

    /**
     * @param sender the sender to set
     */
    @Input(fieldName = SENDER, required = false)
    public void setSender(AbstractSenderRegistry sender) {
        this.sender = sender;
    }

    /**
     * @param encode the encode to set
     */
    @Input(fieldName = ENCODE_SCRIPT, required = false)
    public void setEncode(Script encode) {
        this.encode = encode;
    }

    /**
     * @param template the template to set
     */
    @Input(fieldName = TEMPLATE_SCRIPT, required = false)
    public void setTemplate(Script template) {
        this.template = template;
    }

    /**
     * @param decode the decode to set
     */
    @Input(fieldName = DECODE_SCRIPT, required = false)
    public void setDecode(Script decode) {
        this.decode = decode;
    }

    /**
     * @param enabled the enabled to set
     */
    @Input(fieldName = HABILITADO, required = false, defaultValue = "true")
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}
